#include <math.h>

#import <Foundation/Foundation.h>
#import <GraphicsServices/GraphicsServices.h>
#import <UIKit/UIKit.h>

#import "Panel.h"
#import "Button.h"
#import "keycodeutil.h"

@interface AtPoint: NSObject
{
@public
	double x, y;
}

- (id)initWithX: (double)ax y: (double)ay;
@end

@implementation AtPoint
- (id)initWithX: (double)ax y: (double)ay
{
	self = [super init];
	x = ax;
	y = ay;
	return self;
}
@end

@interface AtSize: NSObject
{
@public
	double width, height;
}

- (id)initWithWidth: (double)w height: (double)h;
@end

@implementation AtSize
- (id)initWithWidth: (double)w height: (double)h
{
	self = [super init];
	width = w;
	height = h;
	return self;
}
@end

@interface PanelArea: NSObject
{
@public
	AtPoint *origin;
	AtSize *size;
@protected
	NSString *key;
}

- (id)initWithKey: (NSString *)k origin: (AtPoint *)p size: (AtSize *)s;
- (id)initWithKey: (NSString *)k x: (double)ax y: (double)ay width: (double)w height: (double)h;
- (id)initWithOrigin: (AtPoint *)p size: (AtSize *)s;
- (id)initWithX: (double)ax y: (double)ay width: (double)w height: (double)h;

- (void)setKey: (NSString *)k;
- (NSString *)key;

- (void)dealloc;

- (BOOL)containsPoint: (AtPoint *)p;
@end

@implementation PanelArea
- (id)initWithKey: (NSString *)k origin: (AtPoint *)p size: (AtSize *)s
{
	self = [super init];
	[key = k retain];
	[origin = p retain];
	[size = s retain];
	return self;
}

- (id)initWithKey: (NSString *)k x: (double)ax y: (double)ay width: (double)w height: (double)h
{
	self = [super init];
	[key = k retain];
	origin = [[AtPoint alloc] initWithX: ax y: ay];
	size = [[AtSize alloc] initWithWidth: w height: h];
	return self;
}

- (id)initWithOrigin: (AtPoint *)p size: (AtSize *)s
{
	self = [super init];
	key = nil;
	[origin = p retain];
	[size = s retain];
	return self;
}

- (id)initWithX: (double)ax y: (double)ay width: (double)w height: (double)h
{
	self = [super init];
	key = nil;
	origin = [[AtPoint alloc] initWithX: ax y: ay];
	size = [[AtSize alloc] initWithWidth: w height: h];
	return self;
}

- (BOOL)containsPoint: (AtPoint *)p
{
	if (origin->x <= p->x && origin->y <= p->y && p->x <= (origin->x + size->width) && p->y <= (origin->y + size->height))
		return YES;
	
	return NO;
}

- (void)setKey: (NSString *)k
{
	[key release];
	[key = k retain];
}

- (NSString *)key
{
	return key;
}

- (void)dealloc
{
	[key release];
	[origin release];
	[size release];
}
@end


@implementation Panel

- (id)initWithFrame: (CGRect)frame image: (NSString *)s
{
	self = [super initWithFrame: frame];
	
	[self setImage: [UIImage imageAtPath: s]];
	[self setAreaByImagePath: s];
	
	[(imagePath = [s copy]) retain];
	
	return self;
}

- (void)dealloc
{
	[imagePath release];
}

- (NSString *)imagePath
{
	return imagePath;
}

- (void)setAreaByImagePath: (NSString *)s
{
	NSString *area = [NSString stringWithContentsOfFile: [[s stringByDeletingPathExtension] stringByAppendingPathExtension: @"area"] encoding: NSASCIIStringEncoding error: nil];
	
	[self setAreaByString: area];
}

- (void)setAreaByString: (NSString *)s
{
	NSArray *lines = [s componentsSeparatedByString: @"\n"];
	
	for (int i = 0; i != [lines count]; ++i)
	{
		NSArray *tokens = [[lines objectAtIndex: i] componentsSeparatedByString: @"\t"];
		if ([tokens count] != 5)
			continue;
		
		int x = [[tokens objectAtIndex: 1] intValue];
		int y = [[tokens objectAtIndex: 2] intValue];
		int width = [[tokens objectAtIndex: 3] intValue];
		int height = [[tokens objectAtIndex: 4] intValue];
		
		NSMutableArray *keyCodeArray = [NSMutableArray arrayWithCapacity: 1];
		NSArray *keys = [[tokens objectAtIndex: 0] componentsSeparatedByString: @","];
		for (int k = 0; k != [keys count]; ++k)
		{
			NSMutableArray *keySetArray = [NSMutableArray arrayWithCapacity: 1];
			
			NSArray *sets = [[[keys objectAtIndex: k] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]] componentsSeparatedByString: @"+"];
			for (int s = 0; s != [sets count]; ++s)
			{
				unsigned char keyCode = virtualKeyCodeForName([[[sets objectAtIndex: s] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]] cStringUsingEncoding: NSASCIIStringEncoding]);
				[keySetArray addObject: [NSNumber numberWithUnsignedChar: keyCode]];
			}
			
			[keyCodeArray addObject: keySetArray];
		}
		
		Button *button = [[Button alloc] initWithFrame: CGRectMake(x, y, width, height) keyCode: [keyCodeArray copy]];
		[button setShowPressFeedback: YES];
		[button setKeyDelegate: self];
		[self addSubview: button];
	}
}

- (void)setKeyDelegate: (id)delegate
{
	keyDelegate = delegate;
}

- (void)keyClicked: (unsigned char)key
{
	[keyDelegate keyClicked: key];
}

- (void)keyPressed: (unsigned char)key
{
	[keyDelegate keyPressed: key];
}

- (void)keyReleased: (unsigned char)key
{
	[keyDelegate keyReleased: key];
}

@end
